<?php

namespace App\Models\System;

use App\Casts\ExplodeImplodeCast;
use App\Enum\Models\System\Config\Type;
use App\Models\BaseModel;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class Config extends BaseModel
{
    /**
     * 配置分组字典名字
     */
    public const DICT_GROUP_NAME = 'sys_config_group';

    /**
     * 配置缓存key
     */
    public const CACHE_KEY = 'CONFIG_LIST';

    /**
     * 可自动填充属性
     */
    protected $fillable = [
        'title',
        'name',
        'group',
        'value',
        'type',
        'remark',
        'prop',
        'sort',
        'is_public',
    ];

    /**
     * 属性默认值
     */
    protected $attributes = [
        'prop' => '',
        'rules' => '',
        'value' => '',
        'is_public' => 0,
        'type' => Type::Input->value,
    ];

    /**
     * 属性自动转换
     */
    protected function casts(): array
    {
        return [
            'sort' => 'int',
            'rules' => ExplodeImplodeCast::class,
            'prop' => 'array',
            'is_public' => 'boolean',
        ];
    }

    /**
     * 根绝type返回value值
     */
    protected function value(): Attribute
    {
        return Attribute::make(
            get: function ($value, $attribute) {
                return match ($attribute['type']) {
                    Type::Select, Type::Selects, Type::Radio, Type::Checkbox, Type::Uploads, Type::Slider => explode(',', $value),
                    default => $value,
                };
            },
            set: function ($value, $attribute) {
                return match ($attribute['type']) {
                    Type::Switch => intval($value) ? 1 : 0,
                    Type::Select, Type::Selects, Type::Radio, Type::Checkbox, Type::Uploads, Type::Slider => implode(',', $value),
                    default => $value,
                };

            }
        );
    }

    /**
     * 获取配置分组
     */
    public static function getDictGroup(): ?Collection
    {
        return Dict::getDictItemsByCode(self::DICT_GROUP_NAME);
    }

    /**
     * 获取所有配置
     */
    public static function getAll(): Collection
    {
        // 使用缓存
        return Cache::rememberForever(self::CACHE_KEY, function () {
            // 查询所有的
            return self::query()->get();
        });
    }

    /**
     * 获取公共的配置 一般用于接口返回
     */
    public static function getPublicKeyValue(): Collection
    {
        return self::getAll()->filter(fn (Config $item) => $item->is_public)
            ->keyBy('name')
            ->map(fn (Config $item) => self::getFormaterValue($item->name, $item->value));
    }

    /**
     * 格式化一些配置的值
     */
    public static function getFormaterValue(string $name, $value = null): mixed
    {
        if ($name == 'basic_cdn') {
            $value = $value ?: request()->getSchemeAndHttpHost();
            // 不是http开头的 返回空字符串
            if (! Str::startsWith($value, 'http')) {
                return '';
            }
            // 拼接结尾的 /
            if (! Str::endsWith($value, '/')) {
                $value .= '/';
            }

            return $value;
        }

        return $value;
    }

    /**
     * 获取key => value
     */
    public static function getAllKeyValue(): Collection
    {
        return self::getAll()->filter(fn (Config $item) => $item->is_public)
            ->keyBy('name')
            ->map(fn (Config $item) => self::getFormaterValue($item->name, $item->value));
    }

    /**
     * 根据name获取配置值 如果没有这个配置 返回$default
     */
    public static function getValueByName(string $name, $default = null): mixed
    {
        return self::getAllKeyValue()->get($name, $default);
    }
}
